#include "stdafx.h"
#if LIT_OGRE_SUPPORT

#include "LitLibraryManager.h"
#include "LitRoot.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#include <Windows.h>
#endif

namespace Lit
{
	Library::Library( const String &name, bool bload )
	{
		mHandle=0; 
		mName=name;
		mLoaded =false;
		if( bload ) load();
	}
	Library::~Library()
	{
		unload();
	}
	bool Library::isLoaded() const{ return mLoaded; }
	void Library::load( ){ 
		if( mLoaded ) return;
		mLoaded = false;
		mHandle = Ogre::DynLibManager::getSingleton().load(mName); 
		if( !mHandle ) 
			throw FileMissing( mName, EXC_LOC ); 
		mLoaded = true;
	}
	void Library::unload(){ 
		if( !mLoaded ) return;
		Ogre::DynLibManager::getSingleton().unload( *mHandle ); 
		mLoaded = false;
	}
	const String &Library::getName() const{ return mName; }

	Library::lib_ptr_t Library::handle() const{ return mHandle; }

	LibraryManager::LibraryManager(){}
	LibraryManager::~LibraryManager(){}

	bool LibraryManager::hasLibrary( const String &name ) const{
		return (mMap.find(name)!=mMap.end());
	}
	LibraryPtr LibraryManager::getLibrary( const String &name ) const{
		if( !hasLibrary( name ) )
			throw ItemMissing( name, "LibraryManager", EXC_LOC );
		return mMap.find( name )->second;
	}
	LibraryManager::iterator LibraryManager::begin() { return mMap.begin(); }
	LibraryManager::iterator LibraryManager::end() { return mMap.begin(); }
	LibraryManager::const_iterator LibraryManager::begin() const{ return mMap.begin(); }
	LibraryManager::const_iterator LibraryManager::end()const{ return mMap.end(); }

	LibraryManager::iterator LibraryManager::findLibrary( const String &name ) {
		return mMap.find( name );
	}
	LibraryManager::const_iterator LibraryManager::findLibrary( const String &name )const{
		return mMap.find( name );
	}
	LibraryPtr LibraryManager::load( const String &name ){
		if( hasLibrary(name) ) {
			LibraryPtr l = findLibrary(name)->second;
			if( l->isLoaded() ) return l;
		}
		LibraryPtr ret(new Library(name, false));
		try{
			ret->load();
			mMap[name] = ret;
			return ret;
		}catch( RuntimeError& e )
		{
			ret.destroy();
			ShowMessageBox( NULL, (e.error()+e.location()), MB_ICONWARNING|MB_OK );
			throw;
		}
		return NULL;
	}
	void LibraryManager::unload( LibraryPtr &p ){
		iterator i = findLibrary(p->getName());
		if( i==mMap.end() ) return;

		if( !hasLibrary( p->getName() ) )
			throw ItemMissing( p->getName(), "LibraryManager", EXC_LOC );
		p->unload();
		p.destroy();
		mMap.erase( i );
			
	}
};

#endif